home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Tools / vg-2.03 / video / s3.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  6.4 KB  |  324 lines

  1. /*
  2.  * Copyright (C) 1992 by Michael Davidson.
  3.  * All rights reserved.
  4.  *
  5.  * Permission to use, copy, modify, and distribute this software
  6.  * and its documentation for any purpose and without fee is hereby
  7.  * granted, provided that the above copyright notice appear in all
  8.  * copies and that both that copyright notice and this permission
  9.  * notice appear in supporting documentation.
  10.  *
  11.  * This software is provided "as is" without express or implied warranty.
  12.  */
  13.  
  14. /*
  15.  * s3.c    - support routines for S3 86C911 based cards
  16.  */
  17.  
  18. #include    "vdev.h"
  19. #include    "video.h"
  20. #include    "v86mode.h"
  21. #include    "vesabios.h"
  22. #include    "svga.h"
  23. #include    "ibm8514.h"
  24.  
  25. /*
  26.  * NOTE: the S3 86C911 is a single chip VGA / SVGA / 8514
  27.  *     While it is not an exact 8514 clone (it doesn't have
  28.  *     a color compare register or fixed pattern registers
  29.  *     and it is programmed into the 8514 compatible modes
  30.  *     differently from an IBM 8514) it is completely compatible
  31.  *     for all of the basic drawing operations.
  32.  *
  33.  *     modes 0x101 - 0x105 are VESA compatible SVGA modes
  34.  *     modes 0x201 - 0x205 are 8514 compatible
  35.  *
  36.  *     the only extended modes supported here are the 256 color
  37.  *     8514 compatible modes
  38.  */
  39.  
  40. /*
  41.  * table of video modes supported for S3 86C911
  42.  */
  43. #define    GRAPHICS    (SVGA_MODE_SUPPORTED | SVGA_GRAPHICS_MODE)
  44. #define    TEXT        (SVGA_MODE_SUPPORTED | SVGA_TEXT_MODE)
  45.  
  46. static struct svga_mode_info s3_modes[] =
  47. {
  48.     {    640,    480,    24,    0x112,    GRAPHICS },
  49.     {    640,    480,    16,    0x111,    GRAPHICS },
  50.     {    640,    480,    15,    0x110,    GRAPHICS },
  51.     {    1024,    768,    8,    0x205,    GRAPHICS },
  52.     {    800,    600,    8,    0x203,    GRAPHICS },
  53.     {    640,    480,    8,    0x101,    GRAPHICS },
  54.     {    320,    200,    8,    0x13,    GRAPHICS },
  55.     {    132,    25,    0,    0x55,    TEXT     },
  56.     {    80,    25,    0,    0x03,    TEXT     },
  57.     {    0,    0,    0,    0,    0     }
  58. };
  59.  
  60. /*
  61.  * S3 i/o registers
  62.  */
  63. static unsigned short s3_byte_regs[] =
  64. {
  65.     DAC_MASK,
  66.     DAC_R_INDEX,
  67.     DAC_W_INDEX,
  68.     DAC_DATA,
  69.     0
  70. };
  71.  
  72. static unsigned short s3_word_regs[] =
  73. {
  74.     DISP_STAT,
  75.     H_TOTAL,
  76.     H_DISP,
  77.     H_SYNC_STRT,
  78.     H_SYNC_WID,
  79.     V_TOTAL,
  80.     V_DISP,
  81.     V_SYNC_STRT,
  82.     V_SYNV_WID,
  83.     DISP_CNTL,
  84.     ADVFUNC_CNTL,
  85.     SUBSYS_STAT,
  86.     SUBSYS_CNTL,
  87.     ROM_PAGE_SEL,
  88.     CUR_Y,
  89.     CUR_X,
  90.     DESTY_AXSTP,
  91.     DESTX_DIASTP,
  92.     ERR_TERM,
  93.     MAJ_AXIS_PCNT,
  94.     GP_STAT,
  95.     CMD,
  96.     SHORT_STROKE,
  97.     BKGD_COLOR,
  98.     FRGD_COLOR,
  99.     WRT_MASK,
  100.     RD_MASK,
  101.     COLOR_CMP,
  102.     BKGD_MIX,
  103.     FRGD_MIX,
  104.     MULTIFUNC_CNTL,
  105.     PIX_TRANS
  106. };
  107.     
  108. static void    s3_reset();
  109. static int    s3_setmode();
  110. static void    s3_clear();
  111. static void    s3_bank_switch();
  112.  
  113. static int    s3_initial_mode = -1;
  114. static int    s3_current_bank    = -1;
  115.  
  116. extern struct    svga_mode_info    *SVGAModeInfo;
  117. extern struct    svga_mode_info    *SVGAModeTable;
  118.  
  119. s3_io_enable()
  120. {
  121.     unsigned short        *ioaddr;
  122.     /*
  123.      * enable the additional i/o addresses
  124.      */
  125.     for (ioaddr = s3_byte_regs; *ioaddr != 0; ioaddr++)
  126.     V86IOEnable(*ioaddr, 1);
  127.  
  128.     for (ioaddr = s3_word_regs; *ioaddr != 0; ioaddr++)
  129.     V86IOEnable(*ioaddr, 2);
  130. }
  131.  
  132. /*ARGSUSED*/
  133. int
  134. s3_init(
  135.     char    *name,
  136.     struct vdev    *v
  137.     )
  138. {
  139.     struct svga_mode_info    *s;
  140.  
  141.     s3_io_enable();
  142.     /*
  143.      * set up additional mode information
  144.      */
  145.     for (s = s3_modes; s->attributes != 0; s++)
  146.     {
  147.     if (s->bios_mode >= 0x100)
  148.     {
  149.         s->scanline_length = (s->depth > 8) ? 2048 : 1024;
  150.         if (s->depth == 24)
  151.         {
  152.         s->red_bits    = 8;
  153.         s->green_bits    = 8;
  154.         s->blue_bits    = 8;
  155.         s->red_shift    = 16;
  156.         s->green_shift    = 8;
  157.         s->blue_shift    = 0;
  158.         }
  159.     }
  160.     }
  161.     svga_setup(v, s3_modes, s3_bank_switch);
  162.  
  163.     v->v_name        = VESAVendorData();
  164.     v->v_reset        = s3_reset;
  165.     v->v_setmode    = s3_setmode;
  166. #if 0
  167.     v->v_clear        = s3_clear;
  168. #endif
  169.  
  170.     s3_initial_mode    = VBiosGetMode();
  171.  
  172.     return  0;
  173. }
  174.  
  175. int
  176. s3_probe()
  177. {
  178.     int        id;
  179.     outw(0x3d4, 0x4838);    /* unlock S3 special registers        */
  180.     outb(0x3d4, 0x30);        /* select chip id register        */
  181.     id = inb(0x3d5);        /* read chip id                */
  182.     outw(0x3d4, 0x0038);    /*   lock S3 special registers        */
  183.     return (id == 0x81 || id == 0x82);
  184. }
  185.  
  186. /*
  187.  * reset86c911()    - reset the S3 graphics processor
  188.  */
  189. static void
  190. reset_86c911()
  191. {
  192.     outw(0x3d4, 0xa039);    /* unlock system control registers     */
  193.     outb(0x3d4, 0x40);        /* select system configuration register    */
  194.     outb(0x3d5, inb(0x3d5)|1);    /* enable enhanced 8514 mode registers    */
  195.     outw(0x3d4, 0x0039);    /* lock system control registers     */
  196.     outw(SUBSYS_CNTL, 0x9000);    /* disable and reset             */
  197.     outw(SUBSYS_CNTL, 0x5000);    /* enable                */
  198. }
  199.  
  200. static void
  201. s3_reset()
  202. {
  203.     reset_86c911();
  204.     if (s3_initial_mode != -1)
  205.     VBiosSetMode(s3_initial_mode);
  206. }
  207.  
  208. /*
  209.  * s3_setmode()
  210.  */
  211. static int
  212. s3_setmode(
  213.     int        i
  214.     )
  215. {
  216.     extern unsigned    R16Shift, G16Shift, B16Shift;
  217.     extern unsigned    R16Bits, G16Bits, B16Bits;
  218.     extern unsigned    R24Shift, G24Shift, B24Shift;
  219.     extern unsigned    R24Bits, G24Bits, B24Bits;
  220.     struct    svga_mode_info    *s;
  221.  
  222.     s = &s3_modes[i];
  223.  
  224.     reset_86c911();
  225.  
  226.     s3_current_bank = -1;
  227.  
  228.     if (s->bios_mode < 0x100)
  229.     {
  230.     VBiosSetMode(s->bios_mode | 0x80);
  231.     if ((VBiosGetMode() & 0x7f) != s->bios_mode)
  232.         return -1;
  233.     }
  234.     else 
  235.     {
  236.     if (VESABiosSetMode(s->bios_mode) != 0)
  237.         return -1;
  238.     }
  239.  
  240.     if (s->attributes & SVGA_TEXT_MODE)
  241.     {
  242.     VBiosDisableBlink();
  243.     VBiosSetCursorPosition(s->width, s->height);
  244.     }
  245.  
  246.     /*
  247.      * make sure start address is 0
  248.      */
  249.     outw(0x3d4, 0x000c);
  250.     outw(0x3d4, 0x000d);
  251.  
  252.     if (s->attributes & SVGA_GRAPHICS_MODE)
  253.     {
  254.     switch (s->depth)
  255.     {
  256.         case 15:
  257.         case 16:
  258.         case 24:
  259.         RGB32Shift[0]    = s->red_shift;
  260.         RGB32Shift[1]    = s->green_shift;
  261.         RGB32Shift[2]    = s->blue_shift;
  262.         RGB32Bits[0]    = s->red_bits;
  263.         RGB32Bits[1]    = s->green_bits;
  264.         RGB32Bits[2]    = s->blue_bits;
  265.         break;
  266.  
  267.         default:
  268.         break;
  269.     }
  270.     }
  271.     SVGAModeInfo    = s;
  272.     return 0;
  273. }
  274.  
  275. /*
  276.  * s3_clear()
  277.  */
  278. static void
  279. s3_clear(
  280.     int        bg
  281.     )
  282. {
  283.     struct    svga_mode_info    *s = SVGAModeInfo;
  284.  
  285.     if (s->bios_mode < 0x100)
  286.     {
  287.     int        n;
  288.  
  289.     n    = s->scanline_length * s->height;
  290.  
  291.     if (s->attributes & SVGA_TEXT_MODE)    /* text mode    */
  292.         memset(0xb8000, bg | (bg << 4), n);
  293.     else
  294.         memset(0xa0000, bg, n);
  295.     return;
  296.     }
  297.  
  298.     WAIT_QUEUE(4);
  299.  
  300.     outw(WRT_MASK, 0x00ff);
  301.     outw(MULTIFUNC_CNTL, PIX_CNTL | 0);
  302.     outw(BKGD_COLOR, bg);
  303.     outw(FRGD_MIX, 0x0007);
  304.  
  305.     WAIT_QUEUE(5);
  306.  
  307.     outw(CUR_X, 0x0000);
  308.     outw(CUR_Y, 0x0000);
  309.     outw(MAJ_AXIS_PCNT, s->scanline_length - 1);
  310.     outw(MULTIFUNC_CNTL, MIN_AXIS_PCNT | (s->height - 1));
  311.  
  312.     outw(CMD, 0x43b3);        /* command    */
  313. }
  314.  
  315. static void
  316. s3_bank_switch(
  317.     int        bank
  318.     )
  319. {
  320.     if (bank != s3_current_bank)
  321.     VESABiosBankSwitch(bank);
  322.     s3_current_bank = bank;
  323. }
  324.